﻿#region Using

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;
using System.Web.Configuration;
using System.Web;
using System.IO;

using SubjectWorkShop.Core;
using SubjectWorkShop.Core.DataStore;

#endregion

namespace SubjectWorkShop.Core.Providers
{
    /// <summary>
    /// The proxy class for communication between
    /// the business objects and the providers.
    /// </summary>
    public class SubjectService
    {
        #region Provider model

        private static SubjectProvider _provider;
        private static SubjectProviderCollection _providers;
        private static object _lock = new object();

        /// <summary>
        /// Gets the current provider.
        /// </summary>
        public static SubjectProvider Provider
        {
            get { LoadProviders(); return _provider; }
        }

        /// <summary>
        /// Gets a collection of all registered providers.
        /// </summary>
        public static SubjectProviderCollection Providers
        {
            get { LoadProviders(); return _providers; }
        }

        /// <summary>
        /// Load the providers from the web.config.
        /// </summary>
        private static void LoadProviders()
        {
            // Avoid claiming lock if providers are already loaded
            if (_provider == null)
            {
                lock (_lock)
                {
                    // Do this again to make sure _provider is still null
                    if (_provider == null)
                    {
                        // Get a reference to the <blogProvider> section
                        SubjectProviderSection section = (SubjectProviderSection)WebConfigurationManager.GetSection("SubjectWS/subjectProvider");

                        // Load registered providers and point _provider
                        // to the default provider
                        _providers = new SubjectProviderCollection();
                        ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(SubjectProvider));
                        _provider = _providers[section.DefaultProvider];

                        if (_provider == null)
                            throw new ProviderException("Unable to load default BlogProvider");
                    }
                }
            }
        }

        #endregion

        #region Settings

        /// <summary>
        /// Loads the settings from the provider and returns
        /// them in a StringDictionary for the BlogSettings class to use.
        /// </summary>
        public static System.Collections.Specialized.StringDictionary LoadSettings()
        {
            LoadProviders();
            return _provider.LoadSettings();
        }

        /// <summary>
        /// Save the settings to the current provider.
        /// </summary>
        public static void SaveSettings(System.Collections.Specialized.StringDictionary settings)
        {
            LoadProviders();
            _provider.SaveSettings(settings);
        }

        #endregion

        #region Data Store
        /// <summary>
        /// Loads settings from data storage
        /// </summary>
        /// <param name="exType">Extension Type</param>
        /// <param name="exId">Extension ID</param>
        /// <returns>Settings as stream</returns>
        public static object LoadFromDataStore(ExtensionType exType, string exId)
        {
            LoadProviders();
            return _provider.LoadFromDataStore(exType, exId);
        }

        /// <summary>
        /// Saves settings to data store
        /// </summary>
        /// <param name="exType">Extension Type</param>
        /// <param name="exId">Extensio ID</param>
        /// <param name="settings">Settings object</param>
        public static void SaveToDataStore(ExtensionType exType, string exId, object settings)
        {
            LoadProviders();
            _provider.SaveToDataStore(exType, exId, settings);
        }

        /// <summary>
        /// Removes object from data store
        /// </summary>
        /// <param name="exType">Extension Type</param>
        /// <param name="exId">Extension Id</param>
        public static void RemoveFromDataStore(ExtensionType exType, string exId)
        {
            LoadProviders();
            _provider.RemoveFromDataStore(exType, exId);
        }

        ///<summary>
        ///</summary>
        ///<returns></returns>
        public static string GetStorageLocation()
        {
            LoadProviders();
            return _provider.StorageLocation();
        }
        #endregion

        #region Pages

        /// <summary>
        /// Returns a Page based on the specified id.
        /// </summary>
        public static Page SelectPage(Guid id)
        {
            LoadProviders();
            return _provider.SelectPage(id);
        }

        /// <summary>
        /// Persists a new Page in the current provider.
        /// </summary>
        public static void InsertPage(Page page)
        {
            LoadProviders();
            _provider.InsertPage(page);
        }

        /// <summary>
        /// Updates an exsiting Page.
        /// </summary>
        public static void UpdatePage(Page page)
        {
            LoadProviders();
            _provider.UpdatePage(page);
        }

        /// <summary>
        /// Deletes the specified Page from the current provider.
        /// </summary>
        public static void DeletePage(Page page)
        {
            LoadProviders();
            _provider.DeletePage(page);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static List<Page> FillPages()
        {
            LoadProviders();
            return _provider.FillPages();
        }

        #endregion
    }
}
